package com.example.demo.demo.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 通过反射了解集合泛型的本质
 * 编译之后集合的泛型是去泛型化的，
 * @author: htc
 * @date: Created in 17:46 2018/3/23.
 */
public class MethodDemo4 {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        Class arrayListClass = arrayList.getClass();

        List<String> list = new ArrayList();
        list.add("abcd");
        Class listClass = list.getClass();

        System.out.println(arrayListClass==listClass);


        ArrayList<String> saList = new ArrayList();
        saList.add("abcd");
        Class salClass = saList.getClass();

        System.out.println(salClass==listClass);


        /**
         * arrayListClass=listClass  salClass=listClass说明编译之后集合的泛型是去泛型化的
         * Java中集合的泛型，是防止错误输入的，只在编译阶段有效,绕过编译就无效了
         * 通过方法的反射可以绕过编译
         */

        //反射的操作都是编译之后的操作
        Class c = list.getClass();
        try {
            Method m = c.getMethod("add",Object.class);
            //通过反射绕过编译
            Object object = m.invoke(list,1);

            list.getClass().getMethod("add",Object.class).invoke(list,5);

            System.out.println(list);


        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        test();
    }


    public static void test(){
        System.out.println("###################");
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);

        Class listClazz = list.getClass();
        try {
            Method method = listClazz.getMethod("add", Object.class);
            method.invoke(list, "aaaa");
            list.getClass().getMethod("add", Object.class).invoke(list, "bbbb");
            System.out.println(list);

            System.out.println(list.get(0).getClass());
            System.out.println(list.get(3).getClass());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
